package com.yc.videoview;

import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.TableLayout;
import ohos.agp.window.service.WindowManager;
import ohos.app.Context;

import java.util.HashMap;
import java.util.Map;

/**
 * 记得添加下面这个权限
 *
 * @since 2021-05-10
 */
public class FloatWindow {
    private static final String DEFAULTTAG = "default_float_window_tag";
    private static Map<String, IFloatWindow> mFloatWindowMap;

    private FloatWindow() {
    }

    /**
     * get
     *
     * @return return
     */
    public static IFloatWindow get() {
        return get(DEFAULTTAG);
    }

    /**
     * get
     *
     * @param tag tag
     * @return return
     */
    public static IFloatWindow get(String tag) {
        return mFloatWindowMap == null ? null : mFloatWindowMap.get(tag);
    }

    /**
     * with
     *
     * @param applicationContext applicationContext
     * @return return
     */
    public static Builder with(Context applicationContext) {
        return new Builder(applicationContext);
    }

    /**
     * destroy
     */
    public static void destroy() {
        destroy(DEFAULTTAG);
    }

    /**
     * destroy
     *
     * @param tag tag
     */
    public static void destroy(String tag) {
        if (mFloatWindowMap == null || !mFloatWindowMap.containsKey(tag)) {
            return;
        }
        IFloatWindow window = mFloatWindowMap.get(tag);
        if (window != null) {
            window.dismiss();
        }
        mFloatWindowMap.remove(tag);
    }

    public static class Builder {
        Context mApplicationContext;
        Component mView;
        private int mLayoutId;
        int mWidth = ComponentContainer.LayoutConfig.MATCH_CONTENT;
        int mHeight = ComponentContainer.LayoutConfig.MATCH_CONTENT;
        int gravity = TableLayout.Alignment.ALIGNMENT_TOP | TableLayout.Alignment.START;
        int xOffset; // Gravity.TOP | Gravity.START;
        int yOffset;
        boolean mShow = true;
        Class[] mActivities;
        int mMoveType = MoveType.fixed;
        long mDuration = 300L;
        private String mTag = DEFAULTTAG;

        private Builder() {

        }

        Builder(Context applicationContext) {
            mApplicationContext = applicationContext;
        }

        /**
         * setView
         *
         * @param view view
         * @return return
         */
        public Builder setView(Component view) {
            mView = view;
            return this;
        }

        /**
         * setView
         *
         * @param layoutId layoutId
         * @return return
         */
        public Builder setView(int layoutId) {
            mLayoutId = layoutId;
            return this;
        }

        /**
         * setWidth
         *
         * @param width width
         * @return return
         */
        public Builder setWidth(int width) {
            mWidth = width;
            return this;
        }

        /**
         * setHeight
         *
         * @param height height
         * @return return
         */
        public Builder setHeight(int height) {
            mHeight = height;
            return this;
        }

        /**
         * setWidth
         *
         * @param screenType screenType
         * @param ratio ratio
         * @return return
         */
        public Builder setWidth(@WindowScreen.screenType int screenType, float ratio) {
            mWidth = (int) ((screenType == WindowScreen.WIDTH ? WindowUtil.getScreenWidth(mApplicationContext) : WindowUtil.getScreenHeight(mApplicationContext)) * ratio);
            return this;
        }

        /**
         * setHeight
         *
         * @param screenType screenType
         * @param ratio ratio
         * @return return
         */
        public Builder setHeight(@WindowScreen.screenType int screenType, float ratio) {
            mHeight = (int) ((screenType == WindowScreen.WIDTH ? WindowUtil.getScreenWidth(mApplicationContext) : WindowUtil.getScreenHeight(mApplicationContext)) * ratio);
            return this;
        }

        /**
         * setX
         *
         * @param x x
         * @return return
         */
        public Builder setX(int x) {
            xOffset = x;
            return this;
        }

        /**
         * setY
         *
         * @param y y
         * @return return
         */
        public Builder setY(int y) {
            yOffset = y;
            return this;
        }

        /**
         * setX
         *
         * @param screenType screenType
         * @param ratio ratio
         * @return return
         */
        public Builder setX(@WindowScreen.screenType int screenType, float ratio) {
            xOffset = (int) ((screenType == WindowScreen.WIDTH ? WindowUtil.getScreenWidth(mApplicationContext) : WindowUtil.getScreenHeight(mApplicationContext)) * ratio);
            return this;
        }

        /**
         * setY
         *
         * @param screenType screenType
         * @param ratio ratio
         * @return return
         */
        public Builder setY(@WindowScreen.screenType int screenType, float ratio) {
            yOffset = (int) ((screenType == WindowScreen.WIDTH ? WindowUtil.getScreenWidth(mApplicationContext) : WindowUtil.getScreenHeight(mApplicationContext)) * ratio);
            return this;
        }

        /**
         * 设置 Activity 过滤器，用于指定在哪些界面显示悬浮窗，默认全部界面都显示
         *
         * @param show 过滤类型,子类类型也会生效
         * @param activities 过滤界面
         * @return return
         */
        public Builder setFilter(boolean show, Class... activities) {
            mShow = show;
            mActivities = activities;
            return this;
        }

        /**
         * setMoveType
         *
         * @param moveType moveType
         * @return return
         */
        public Builder setMoveType(@MoveType.MOVE_TYPE int moveType) {
            mMoveType = moveType;
            return this;
        }

        /**
         * setMoveStyle
         *
         * @param duration duration
         * @return return
         */
        public Builder setMoveStyle(long duration) {
            mDuration = duration;
            return this;
        }

        /**
         * setTag
         *
         * @param tag tag
         * @return return
         */
        public Builder setTag(String tag) {
            mTag = tag;
            return this;
        }

        /**
         * build
         *
         * @throws IllegalArgumentException IllegalArgumentException
         */
        public void build() {
            if (mFloatWindowMap == null) {
                mFloatWindowMap = new HashMap<>();
            }
            if (mFloatWindowMap.containsKey(mTag)) {
                throw new IllegalArgumentException("FloatWindow of this tag has been added, "
                    + "Please set a new tag for the new FloatWindow");
            }
            if (mView == null && mLayoutId == 0) {
                throw new IllegalArgumentException("View has not been set!");
            }
            if (mView == null) {
                WindowManager.getInstance();

                LayoutScatter inflate = (LayoutScatter)
                    mApplicationContext.getApplicationContext();

                if (inflate != null) {
                    mView = inflate.parse(mLayoutId, null, false);
                }
            }
            IFloatWindow floatWindowImpl = new IFloatWindowImpl(this);
            mFloatWindowMap.put(mTag, floatWindowImpl);
        }
    }
}
